
#ifndef _MPSSED_IO_DEF_H_
#define _MPSSED_IO_DEF_H_

#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
#include <at32f403a_407_usb.h>
#include "io_init.h"

#ifndef PACKED
#define PACKED __attribute__ ((packed))
#endif

#ifndef INLINE
#define INLINE static inline
#endif

extern int CLK_SET_V;       //一般MCU高位与低位处理
extern int CLK_CLR_V;

INLINE void delay_tim(){
    while(TMR3->cval<100);
    TMR3->cval = 0;
}

static void _set_gpio_out(gpio_type*gpio,uint32_t pin_bit);
static void _set_gpio_in(gpio_type*gpio,uint32_t  pin_bit);
static void _set_gpio_od(gpio_type*gpio,uint32_t  pin_bit);

#if 0
static void _set_gpio_mode(gpio_type*gpio,uint32_t pin_bit,uint32_t mode){
    mode <<= (pin_bit&7)*4;
    uint32_t mode_mask = ~(0b1111 << ((pin_bit & 7) *4) );

    if(pin_bit<8){
        gpio->cfglr = (gpio->cfglr&mode_mask) | mode;
    }
    else{
        gpio->cfghr = (gpio->cfghr&mode_mask) | mode;
    }
}

static void _set_gpio_out(gpio_type*gpio,uint32_t pin_bit){
    uint32_t mode = 0b10;           //适中的输出
    mode |= 0b00 << 2;              //通用推挽
    _set_gpio_mode(gpio,pin_bit,mode);
}

static void _set_gpio_in(gpio_type*gpio,uint32_t pin_bit){
    uint32_t mode = 0b00;           //输入
    mode |= 0b10 << 2;              //浮空
    _set_gpio_mode(gpio,pin_bit,mode);
    gpio->odt &= ~(1<<pin_bit);
}

static void _set_gpio_od(gpio_type*gpio,uint32_t pin_bit){
    uint32_t mode = 0b10;           //适中的输出
    mode |= 0b01 << 2;              //开漏
    _set_gpio_mode(gpio,pin_bit,mode);
}
#endif

#define GPIOL1_Bit      0
#define TCK_PIN_Bit     15
#define TMS_PIN_Bit     14
#define TDO_PIN_Bit     13
#define TDI_PIN_Bit     12


static void _set_dir_(int ish,uint32_t pin,uint32_t dir){
    if(ish==0){
        //低8位
        int i=0;
        for(i=0;i<8;i++){
            int pin_bit = i;
            switch(i){
                case 0x0:pin_bit = TCK_PIN_Bit; break;
                case 0x1:pin_bit = TDI_PIN_Bit; break;
                case 0x2:pin_bit = TDO_PIN_Bit; break;
                case 0x3:pin_bit = TMS_PIN_Bit; break;
            }
            if(dir&(1<<i)){
                //设置为输出
                _set_gpio_out(GPIOB,pin_bit);

                if(pin_bit==TCK_PIN_Bit){
                    // if((pin&(1<<i))==0){
                    //     /*
                    //     拉低引脚
                    //     */
                    //     CLK_SET_V = 1<<pin_bit <<16;
                    //     CLK_CLR_V = 1<<pin_bit;
                    // }
                    // else{
                    //     CLK_SET_V = 1<<pin_bit;
                    //     CLK_CLR_V = 1<<pin_bit << 16;
                    // }

                    CLK_SET_V = 1<<pin_bit;
                    CLK_CLR_V = 1<<pin_bit << 16;
                }


                if(pin&(1<<i)){
                    //置为1
                    GPIOB->scr <<= (1<<pin_bit);
                }
                else{
                    //置为0
                    GPIOB->scr <<= (1<<pin_bit)<<16;
                }

            }
            else{
                //设置为输入
                _set_gpio_in(GPIOB,pin_bit);
                GPIOB->scr = 1<<pin_bit;
            }
        }
    }
    else{
        //其他的都错误
    }
}

static uint8_t _get_pin_sts(int ish){
    if(ish==0){
        int v = 0;
        v |= ((GPIOB->idt>>TCK_PIN_Bit)&1)<<0;
        v |= ((GPIOB->idt>>TDI_PIN_Bit)&1)<<1;
        v |= ((GPIOB->idt>>TDO_PIN_Bit)&1)<<2;
        v |= ((GPIOB->idt>>TMS_PIN_Bit)&1)<<3;
        return v;
    }
    else{
        return 0;
    }
}


#define TMS_REG_V           (1<<TMS_PIN_Bit)
#define TDI_REG_V           (1<<TDI_PIN_Bit)
#define GPIO_OUT_SET(val)   GPIOB->scr = val;
#define CLK_POS             GPIOB->scr = CLK_SET_V;
#define CLK_NEG             GPIOB->scr = CLK_CLR_V;
#define TDO_GET             ((GPIOB->idt>>TDO_PIN_Bit)&1)
#define SET_PIN_DIR(ish,pin,dir) _set_dir_(ish,pin,dir)
#define GET_PIN_STS(ish)         _get_pin_sts(ish)
#define DELAY_TIM                delay_tim();
#define GPIOL1_VAL          ((GPIOB->idt>>GPIOL1_Bit)&1)
#define CLK_STS             ((GPIOB->odt>>TCK_PIN_Bit)&1)
#define TDI_SET             GPIOB->scr = ((1<<TDI_PIN_Bit))
#define TDI_CLR             GPIOB->scr = ((1<<TDI_PIN_Bit)<<16)

#endif

